package com.waterflow.xanner;

import com.waterflow.xanner.model.PlayerProgress;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Interpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class PuzzleActivity extends Activity {

	private PlayerProgress progress;
	ObjectAnimator animator = null;
	MediaPlayer soundEffect;
	private boolean coversOpen = false;
	private Runnable hideObject = new Runnable() {
		@Override
		public void run() {
			findViewById(R.id.puzzle_object).setVisibility(View.INVISIBLE);
		}
	};
	private Runnable showObject = new Runnable() {
		@Override
		public void run() {
			findViewById(R.id.puzzle_object).setVisibility(View.VISIBLE);
		}
	};

	private static final int COVERS_ANIMATION_LENGTH = 1000;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Load Levels and Saved Progress
		progress = new PlayerProgress(this);
		progress.loadProgress(this);

		// Inflate XML layout
		setContentView(R.layout.activity_puzzle);

		// Disable hardware acceleration for performance
		findViewById(R.id.puzzle_object_text).setLayerType(
				View.LAYER_TYPE_SOFTWARE, null);

		EditText textField = (EditText) findViewById(R.id.input_answer);
		textField.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
				checkAnswer();
			}
		});

		setupTitleAndPuzzle();

		try {
			AssetFileDescriptor afd = getAssets().openFd("correct.mp3");
			soundEffect = new MediaPlayer();
			soundEffect.setDataSource(afd.getFileDescriptor(),
					afd.getStartOffset(), afd.getLength());
			soundEffect.prepare();
		} catch (Exception e) {
			e.printStackTrace();
			Log.e("APP_ERROR", e.getMessage());
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		progress.loadProgress(this);
	}

	@Override
	protected void onPause() {
		super.onPause();
		progress.saveProgress(this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	private void setupTitleAndPuzzle() {
		View textview = findViewById(R.id.puzzle_object_text);
		ImageView imview = (ImageView) findViewById(R.id.puzzle_object_image);
		View view;
		
		if(progress.currentLevel().str.startsWith("image:")){
			
			imview.setImageResource(R.drawable.android_white);
			imview.setVisibility(View.VISIBLE);
			textview.setVisibility(View.GONE);
			view = imview;
		} else {
			// Set up puzzle text
			((TextView) textview).setText(progress.currentLevel().str);
			textview.setVisibility(View.VISIBLE);
			imview.setVisibility(View.GONE);
			view = textview;
		}

		
		// Set up Title
		((TextView) findViewById(R.id.level_title)).setText("Level "
				+ (progress.currentLevelIndex() + 1));

		// Show/Hide Navigation Buttons
		if (progress.canGoToPreviousLevel()) {
			findViewById(R.id.button_prev_level).setVisibility(View.VISIBLE);
		} else {
			findViewById(R.id.button_prev_level).setVisibility(View.GONE);
		}
		if (progress.canGoToNextLevel()) {
			findViewById(R.id.button_next_level).setVisibility(View.VISIBLE);
		} else {
			findViewById(R.id.button_next_level).setVisibility(View.GONE);
		}

		// Start the animation as soon as the text view is on the screen
		view.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {
					@Override
					public void onGlobalLayout() {
						startAnimation();
					}
				});
	}

	private void startAnimation() {
		if (animator != null) {
			animator.cancel();
		}

		View view = findViewById(R.id.puzzle_object);

		float height = view.getHeight();

		animator = ObjectAnimator.ofFloat(view, "translationY", height / 2,
				-height / 2);

		animator.setDuration(progress.currentLevel().duration);

		animator.setRepeatCount(ObjectAnimator.INFINITE);

		animator.setInterpolator(new Interpolator() {

			@Override
			public float getInterpolation(float input) {
				return input;
			}
		});

		animator.start();
	}

	public void onClickNavigationRight(View view) {
		hideObject.run();
		closeCovers();
		progress.nextLevel();
		clearTextInput();
		setupTitleAndPuzzle();
	}

	public void onClickNavigationLeft(View view) {
		hideObject.run();
		closeCovers();
		progress.previousLevel();
		clearTextInput();
		setupTitleAndPuzzle();
	}

	private void checkAnswer() {
		EditText textField = (EditText) findViewById(R.id.input_answer);
		String answer = textField.getText().toString();
		if (progress.trySolution(answer)) {
			InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			imm.hideSoftInputFromWindow(textField.getWindowToken(), 0);
			findViewById(R.id.input_answer).setBackgroundColor(
					getResources().getColor(
							R.color.input_field_background_success));
			playSound();
			setupTitleAndPuzzle();
			openCovers();
		}
	}

	private void clearTextInput() {
		EditText textField = (EditText) findViewById(R.id.input_answer);
		textField.setText("");
		findViewById(R.id.input_answer).setBackgroundColor(
				getResources().getColor(R.color.input_field_background));
	}

	private void openCovers() {
		if (coversOpen) {
			return;
		}

		coversOpen = true;

		float startThickness = getResources().getDimension(
				R.dimen.slit_thickness);
		float endThickness = getResources().getDimension(
				R.dimen.slit_thickness_answer_revealed);

		animateSlit(startThickness, endThickness, null);
	}

	private void closeCovers() {
		float startThickness = getResources().getDimension(
				R.dimen.slit_thickness);
		float endThickness = getResources().getDimension(
				R.dimen.slit_thickness_answer_revealed);

		if (!coversOpen) {
			showObject.run();
			return;
		}

		coversOpen = false;

		animateSlit(endThickness, startThickness, showObject);
	}

	private void animateSlit(float start, float end, final Runnable onEnd) {
		final View slit = findViewById(R.id.slit_window);

		final ViewGroup.LayoutParams params = slit.getLayoutParams();

		Object modifier = new Object() {
			@SuppressWarnings("unused")
			public void setHeight(float height) {
				params.height = (int) height;
				slit.setLayoutParams(params);
			}
		};

		ObjectAnimator animatorSlit = ObjectAnimator.ofFloat(modifier,
				"Height", start, end);
		animatorSlit.setDuration(COVERS_ANIMATION_LENGTH);
		if (onEnd != null) {
			animatorSlit.addListener(new AnimatorListener() {

				@Override
				public void onAnimationStart(Animator animation) {
				}

				@Override
				public void onAnimationRepeat(Animator animation) {
				}

				@Override
				public void onAnimationEnd(Animator animation) {
					onEnd.run();
				}

				@Override
				public void onAnimationCancel(Animator animation) {
					onEnd.run();
				}
			});
		}

		animatorSlit.start();
	}

	private void playSound() {
		SharedPreferences prefs = getSharedPreferences(
				SettingsActivity.PREFERENCES_NAME, Context.MODE_PRIVATE);
		if (!prefs.getBoolean(SettingsActivity.KEY_MUTE_ON, false)) {
			soundEffect.start();
		}
	}
}
